package com.etc.shiro;

import com.etc.shiro.model.AuthMst;
import com.etc.shiro.model.RoleMst;
import com.etc.shiro.model.UserMst;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 由于Shiro filterChainDefinitions中 roles默认是and，
 * = user,roles[system,general]
 * 比如：roles[system,general] ，表示同时需要“system”和“general” 2个角色才通过认证
 * 但是在实际业务中，一个端口的权限往往对多个角色开放（比如管理员可以使用一切权利）
 */
public class MyRolesAuthorizationFilter extends AuthenticationFilter {



    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        Subject subject = getSubject(request, response);

        UserMst user = (UserMst)subject.getSession().getAttribute("user");
        if (user != null) {
            String[] rolesArray = (String[]) mappedValue;
            if (request instanceof HttpServletRequest) {
                String path = ((HttpServletRequest) request).getServletPath();

                List<AuthMst> plist = new ArrayList<>();
                user.getRlist().forEach(item -> item.getPlist().forEach(plist::add));
                if (plist.stream().map(AuthMst::getPath).filter(
                        item -> path.matches(item)
                ).count() != 0) {
                    return true;
// TODO锁定path字段--数据库正则必须匹配
//                } else
//                    response 处理
//                    return false;
                }
            }
        }

         String[] rolesArray = (String[]) mappedValue;
        //没有权限访问
        if (rolesArray == null || rolesArray.length == 0) {
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++) {
            //若当前用户是rolesArray中的任何一个，则有权限访问
            if (subject.hasRole(rolesArray[i])) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
       return false;
    }

}
